import Vue from "vue";

import VueRouter from "vue-router";

/* import Login from "@/pages/Login";
import Home from "@/pages/Home";
import Music from "@/pages/Home/components/Music";
import Game from "@/pages/Home/components/Game";
import News from "@/pages/Home/components/News";
import NotFound from "@/pages/404"; */

/* 
  把路由组件进行异步组件处理的方式,被称作为路由组件懒加载(路由懒加载)

*/
const Login = () => import("@/pages/Login");
const Home = () => import("@/pages/Home");
const NotFound = () => import("@/pages/404");
const Music = () => import("@/pages/Home/components/Music");
const Game = () => import("@/pages/Home/components/Game");
const News = () => import("@/pages/Home/components/News");
const MusicItem = () => import("@/pages/Home/components/Music/Item");

//把VueRouter作为插件使用
Vue.use(VueRouter);

//重写VueRouter原型对象上的push方法
const oldPush = VueRouter.prototype.push;
VueRouter.prototype.push = function (
  location,
  onComplete = () => {},
  onAbort = () => {}
) {
  //调用原来的push
  oldPush.call(this, location, onComplete, onAbort);
};

//实例化VueRouter 得到 router对象
const router = new VueRouter({
  mode: "history",
  //配置路由表
  routes: [
    /* !!!!默认路由 */
    {
      path: "/",
      //重定向
      redirect: "/home",
    },
    {
      path: "/login",
      component: Login,
      /* 
        命名路由
          有时候，通过一个名称来标识一个路由显得更方便一些，特别是在链接一个路由，或者是执行一些跳转的时候。
          可以在创建 Router 实例的时候，在 routes 配置中给某个路由通过name属性设置名称。
      
      */
      name: "login",
    },
    {
      path: "/home",
      name: "home",
      component: Home,
      /* !!!!默认子路由(推荐方式) */
      redirect: "/home/music",
      children: [
        {
          path: "/home/music",
          component: Music,
          name: "music",
          meta: {
            icon: "图标",
            title: "音乐",
          },
          children: [
            {
              path: "/home/music/item/:id/:name?",
              component: MusicItem,
              name: "MusicItem",
              //当路由表中配置一个props,且值为true,则代表当前路由会把params参数通过props的形式传递到组件内部
              // props: true,
              //当路由表中配置一个props,值是一个对象,则或把对象中的属性通过props的方式传递给组件内部
              // props: {
              //   a1: "1",
              //   a2: "2",
              // },
              //当路由表中配置一个props，且值为函数,函数的参数就是当前的$route对象,函数return的对象中的属性,就是通过props传递给组件内部的值
              props($route) {
                return {
                  ...$route.params,
                  ...$route.query,
                  a1: "1",
                  a2: "2",
                };
              },
            },
          ],
        },
        {
          path: "/home/news",
          component: News,
          name: "news",
          meta: {
            icon: "图标",
            title: "新闻",
          },
        },
        {
          path: "/home/Game",
          component: Game,
          name: "game",
          meta: {
            icon: "图标",
            title: "游戏",
          },
          //路由独享守卫
          beforeEnter: (to, from, next) => {
            console.log("我要进游戏了");
            //放行
            // next();
            //导航到其他
            console.log("我要去login了");
            next("/login");
          },
        },
      ],
    },
    {
      path: "/*",
      component: NotFound,
    },
  ],
});
//配置 全局前置守卫
//参数1.to代表目标组件的$route对象 from代表来的组件的$route对象
//next是放行函数
router.beforeEach((to, from, next) => {
  console.log("全局前置守卫", to, from);
  next();
});

//全局解析守卫 导航被确认前 同时在所有组件内守卫和异步路由组件被解析之后，解析守卫就被调用
router.beforeResolve((to, from, next) => {
  console.log("全局解析守卫", to, from);
  next();
});

//全局后置钩子
router.afterEach((to, from) => {
  console.log("全局后置钩子", to, from);
});
export default router;
